<template>
  <div>
    <a-row :gutter="24" >

      <a-col :span="8">
        <a-card :bordered="true" title="菜单树" :bodyStyle="bodyStyle" :headStyle="headStyle">
          <!-- extra -->
          <template v-slot:extra>
            <!-- 手动创建 -->
            <a-tooltip title="创建菜单">
              <a-icon
                type="plus-circle"
                @click="addMenu"
                theme="twoTone"
                :style="{ fontSize: '20px'}"
              />
            </a-tooltip>
          </template>
          <menu-tree
            ref="menutree"
            @selectMenuNode="selectMenuNode"
          ></menu-tree>
        </a-card>
      </a-col>
      <a-col :span="16" >
        <a-card :bordered="true">
          <s-table
            ref="stable"
            size="default"
            :columns="columns"
            :data="loadData"
          >
            <span slot="action" slot-scope="text, record">
              <a @click="detailMenu(record)">详情</a>
              <a-divider type="vertical" />
              <a @click="editMenu(record)" v-action:update>编辑</a>
              <a-divider type="vertical" />
              <a @click="delMenu(record)" v-action:delete>删除</a>
            </span>
          </s-table>
          <!-- 弹出页 -->
          <a-modal
            title="菜单"
            style="top: 100px;"
            :width="800"
            v-model="visible"
            @ok="handleOK"
            :destroyOnClose="true"
            :confirmLoading="confirmLoading"
          >
            <a-form :form="addForm" >
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="菜单名称"
              >
                <a-input v-model="addForm.title" :disabled="inDetail"/>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="上级菜单"
                :labelInValue="true"
              >
                <a-select
                  size="default"
                  v-model="addForm.parentId"
                  :disabled="inDetail"
                >
                  <a-select-option v-for="menu in menulist" :value="menu.id" :key="menu.id">
                    {{ menu.title }}
                  </a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="路径编码"
              >
                <a-input v-model="addForm.code" :disabled="inDetail"/>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="资源路径"
              >
                <a-input v-model="addForm.uri" :disabled="inDetail || inEdit"/>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="资源菜单类型"
              >
                <a-select
                  size="default"
                  v-model="addForm.type"
                  :disabled="inDetail"
                >
                  <a-select-option v-for="type in typelist" :value="type.id" :key="type.id">
                    {{ type.title }}
                  </a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="排序"
              >
                <a-input v-model="addForm.orderNum" type="number" :disabled="inDetail"/>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="菜单类型"
              >
                <a-select
                  size="default"
                  v-model="addForm.attr1"
                  :disabled="inDetail"
                >
                  <a-select-option v-for="attr1 in attr1list" :value="attr1.id" :key="attr1.id">
                    {{ attr1.title }}
                  </a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="描述"
              >
                <a-input v-model="addForm.description" :disabled="inDetail"/>
              </a-form-item>
              <a-form-item
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="按钮"
              >
                <a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll" :disabled="inDetail">
                  全选
                </a-checkbox>
                <br/>
                <a-checkbox-group :options="elementOpt" v-model="elements" @change="elementChange" :disabled="inDetail"/>
              </a-form-item>
            </a-form>
          </a-modal>
        </a-card>
      </a-col></a-row>
  </div>
</template>
<script>
import { STable } from '@/components'
import MenuTree from '@/components/admin/MenuTree'
import { query, method } from '@/api/admin'
export default {
  name: 'MenuList',
  components: {
    STable,
    MenuTree
  },
  data () {
    return {
      visible: false,
      form: this.$form.createForm(this),
      // 查询参数
      queryParam: {},
      inAdd: false,
      inEdit: false,
      inDetail: false,
      inDelete: false,
      // 上级菜单下拉框内容
      menulist: [],
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => {
        return query('/admin/pmMenu/page', 'GET', parameter)
          .then(res => {
            return res.result
          })
      },
      typelist: [// base基础菜单，biz业务菜单，system系统菜单
        { title: '基础菜单', id: 'base' },
        { title: '业务菜单', id: 'biz' },
        { title: '系统菜单', id: 'system' }
      ],
      attr1list: [
        { title: '目录菜单', id: '1' },
        { title: '业务菜单', id: '2' }
      ],
      // 表头
      columns: [
        {
          title: '菜单名称',
          dataIndex: 'title'
        },
        {
          title: '路径编码',
          dataIndex: 'code'
        },
        {
          title: '资源路径',
          dataIndex: 'uri'
        },
        {
          title: '资源菜单类型',
          dataIndex: 'type',
          key: 'type',
          customRender: function (type) {
            if (type === 'base') {
              return '基础菜单'
            } else if (type === 'biz') {
              return '业务菜单'
            } else if (type === 'system') {
              return '系统菜单'
            }
          }
        },
        {
          title: '菜单类型',
          dataIndex: 'attr1',
          key: 'attr1',
          customRender: function (attr1) {
            if (attr1 === '1') {
              return '目录菜单'
            } else {
              return '业务菜单'
            }
          }
        },
        {
          title: '描述',
          dataIndex: 'description'
        },
        {
          title: '操作',
          width: '200px',
          dataIndex: 'action',
          scopedSlots: { customRender: 'action' }
        }
      ],
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      confirmLoading: false,
      addForm: {
        title: '',
        parentId: '',
        code: '',
        uri: '',
        type: '',
        orderNum: '',
        attr1: '',
        description: ''
      },
      menuId: '',
      currentitem: '', // 点击菜单节点
      elementOpt: [
        { label: '新增', value: 'add' },
        { label: '修改', value: 'update' },
        { label: '删除', value: 'delete' },
        { label: '查询', value: 'query' },
        { label: '上传', value: 'upload' },
        { label: '下载', value: 'download' },
        { label: '导入', value: 'import' },
        { label: '导出', value: 'export' }
      ],
      // 用于将数据改成后台接收的格式
      methodsMap: new Map([
        [ 'add', { 'code': 'add', 'method': 'POST', 'name': '新增' } ],
        [ 'update', { 'code': 'update', 'method': 'PUT', 'name': '修改' } ],
        [ 'delete', { 'code': 'delete', 'method': 'DELETE', 'name': '删除' } ],
        [ 'query', { 'code': 'query', 'method': 'GET', 'name': '查询' } ],
        [ 'upload', { 'code': 'upload', 'method': 'POST', 'name': '上传' } ],
        [ 'download', { 'code': 'download', 'method': 'GET', 'name': '下载' } ],
        [ 'import', { 'code': 'import', 'method': 'POST', 'name': '导入' } ],
        [ 'export', { 'code': 'export', 'method': 'GET', 'name': '导出' } ]
      ]),
      indeterminate: false,
      checkAll: false,
      elements: [],
      bodyStyle: {
        padding: '12px',
        height: '600px',
        overflow: 'auto'
      },
      headStyle: {
        'margin-left': '20px',
        'margin-right': '20px',
        'margin-top': '15px'
      }
    }
  },
  created () {
    // 获取下拉菜单
    this.getMenulist()
  },
  methods: {
    /**
     * 点击菜单树节点触发右侧列表查询
     */
    selectMenuNode (node) {
      this.currentitem = node
      this.$refs.stable.loadData({}, Object.assign(this.queryParam, { 'id': this.currentitem.key }))
    },
    /**
     * 新增菜单
     */
    addMenu () {
      this.inAdd = true
      this.inEdit = false
      this.inDetail = false
      this.visible = true
      this.bindFormData({ 'parentId': this.currentitem.key })
      this.elements = []
      this.indeterminate = false
    },
    /**
     * 菜单查看
     */
    detailMenu (record) {
      this.inAdd = false
      this.inEdit = false
      this.inDetail = true
      this.bindFormData(record)
      this.visible = true
    },
    /**
     * 编辑菜单
     */
    editMenu (record) {
      this.inAdd = false
      this.inEdit = true
      this.inDetail = false
      this.bindFormData(record)
      this.visible = true
    },
    /**
     * form表单绑定数据
     */
    bindFormData (record) {
      this.addForm = Object.assign({}, record)
      if (!this.inAdd) {
        query('/admin/pmMenu/_search/' + record.id, 'GET', {}, {}).then(res => {
          const result = res.result.elements.map(item => item.code)
          this.elements = result
          if (result.length === this.elementOpt.length) {
            this.checkAll = true
          } else {
            this.checkAll = false
            this.indeterminate = result.length > 0
          }
        })
      }
    },
    /**
     * 删除菜单
     */
    delMenu (record) {
      this.menuId = record.id
      const _this = this
      this.$confirm({
        title: '警告',
        content: `确认要删除 ${record.title} 吗?`,
        okText: '确认',
        okType: 'danger',
        cancelText: '取消',
        onOk () {
          _this.inDelete = true
          _this.handleOK()
        },
        onCancel: () => {
          this.$notification['info']({
            message: '取消删除操作',
            duration: 4
          })
        }
      })
    },
    /**
     * 请求菜单下拉框
     */
    getMenulist () {
      query('/admin/pmMenu/all', 'GET', {}, {}).then(res => {
        this.menulist = res.result.data
      })
    },
    /**
     * 保存提交
     */
    handleOK () {
      if ((this.inAdd || this.inEdit) && (this.addForm.title === '' || this.addForm.title === undefined)) {
        this.$notification['info']({
          message: '请填写菜单名称',
          duration: 4
        })
        return
      }
      // 对返回后端的按钮数据做处理
      this.addForm.elements = this.handleElement()
      // 如果不选择上级菜单，即为根目录
      if (this.addForm.parentId === '') {
        this.addForm.parentId = 'root'
      }
      const actionParam = {// 请求参数
        'url': '',
        'action': '',
        'parameter': {},
        'data': this.addForm,
        'message': '操作成功'
      }
      if (this.inAdd) {
        actionParam.url = '/admin/pmMenu/insertMenu'
        actionParam.action = 'post'
        // 调用请求
        method(actionParam).then(res => {
          this.allRefresh()
        })
      } else if (this.inEdit) {
        actionParam.url = '/admin/pmMenu/modifyMenu'
        actionParam.action = 'put'
        method(actionParam).then(res => {
          this.allRefresh()
        })
      } else if (this.inDelete) {
        actionParam.url = '/admin/pmMenu/deleteMenu'
        actionParam.action = 'delete'
        actionParam.data = { 'id': this.menuId }
        method(actionParam).then(res => {
          this.allRefresh()
        })
      }
    },
    /**
     * 页面数据刷新
     */
    allRefresh () {
      this.inAdd = false
      this.inEdit = false
      this.inDelete = false
      this.visible = false // 关闭编辑框
      this.$refs.stable.loadData({}, Object.assign(this.queryParam, { 'id': this.currentitem.key }))
      this.$refs.menutree.getMenuTree() // 刷新树
    },
    /**
     * 对请求到后端的数据做处理
     */
    handleElement () {
      const elements = this.elements
      if (elements.length === 0) {
        return []
      } else {
        const value = elements.map(data => {
          return this.methodsMap.get(data)
        })
        return value
      }
    },
    /**
     * 多选框change事件
     */
    elementChange (checkedList) {
      this.elements = checkedList
      this.indeterminate = !!checkedList.length && checkedList.length < this.elementOpt.length
      this.checkAll = checkedList.length === this.elementOpt.length
    },
    /**
     * 全选change事件
     */
    onCheckAllChange (e) {
      this.elements = e.target.checked ? this.elementOpt.map(data => data.value) : []
      Object.assign(this, {
        indeterminate: false,
        checkAll: e.target.checked
      })
    }
  }
}
</script>
<style>

</style>
